package com.yuncheng.spcyApi.flowService;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.yuncheng.entity.YcSysUser;
import com.yuncheng.vo.GetKsKz;
import com.yuncheng.vo.CurrentUserVo;
import com.yuncheng.vo.HttpResult;
import org.apache.commons.collections.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yuncheng.spcyApi.busService.BusService;
import com.yuncheng.spcyApi.config.SpcyMinioUtils;
import com.yuncheng.spcyApi.constant.common.BusinessConstant;
import com.yuncheng.spcyApi.constant.common.LogConstant;
import com.yuncheng.spcyApi.constant.common.SpcyConstant;
import com.yuncheng.spcyApi.constant.flow.YlqxFlowConstant;
import com.yuncheng.spcyApi.constant.flow.ZltxwjFlowConstant;
import com.yuncheng.spcyApi.entity.*;
import com.yuncheng.exception.BusinessException;
import com.yuncheng.spcyApi.service.*;
import com.yuncheng.spcyApi.service.impl.YcSysUserServiceImpl;
import com.yuncheng.spcyApi.utils.*;
import com.yuncheng.spcyApi.vo.common.Result;
import com.yuncheng.spcyApi.vo.flow.AgentVo;
import com.yuncheng.spcyApi.vo.flow.CommonFlowVo;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import utils.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

/** 旧的体系文件流程 */
@Component(value = "zltxwjFlowService")
public class ZltxwjFlowService extends FlowService {
    private static final Logger log = LoggerFactory.getLogger(ZltxwjFlowService.class);

    @Resource
    @Lazy
    private ZltxwjFlowConstant flowConstant;

    @Resource
    @Lazy
    private ISpcySqsxJobService spcySqsxJobService;

    @Resource
    @Lazy
    private ISysUserFgldService sysUserFgldService;

    @Resource
    @Lazy
    private YcSysUserServiceImpl ycSysUserService;

    @Resource
    @Lazy
    private ISpcyLogService spcyLogService;

    @Resource
    @Lazy
    private BusService busService;

    @Resource
    @Lazy
    private ISpcyZltxwjBasicService spcyZltxwjBasicService;

    @Resource
    @Lazy
    private ISpcyZltxwjFlowService spcyZltxwjFlowService;

    @Resource
    @Lazy
    private ISpcyZltxwjHistoryService spcyZltxwjHistoryService;

    @Resource
    @Lazy
    private ISpcySqsxWjjlService spcySqsxWjjlService;

    @Resource
    private BusinessConstant businessConstant;

    @Resource
    private LocalFileUploadUtils localFileUploadUtils;

    @Resource
    private WordPdfUtils wordPdfUtils;

    @Resource
    private SpcyMinioUtils spcyMinioUtils;

    public Result handleFlow(CommonFlowVo commonFlowVo, SpcySqsxJob nowJob, String jobId, String ywid, String submitType, String opinion){
        // 当前流程任务
        if (StringUtils.isNotBlank(jobId)) {
            nowJob = spcySqsxJobService.getById(jobId);
        }

        if (nowJob == null){
            return Result.error("当前流程任务不存在，请重试");
        }

        if (StringUtils.isBlank(ywid)){
            ywid = nowJob.getFpid();
        }

        // 提交按钮
        if (submitType.equals(ZltxwjFlowConstant.SUBMIT_TYPE_SUBMIT)) {
            if (nowJob == null) {
                return Result.error("当前流程任务不存在");
            }
        }
        CurrentUserVo currentUser = GetCurrentUserUtils.getCurrentUser();
        if (currentUser == null){
            return Result.error("登录已失效，请重新登录");
        }

        if (nowJob.getFhjmc().equals(ZltxwjFlowConstant.HJMC_KSFH)){

            String deptName = "";
            SpcyZltxwjFlow zltxwj = spcyZltxwjFlowService.getById(ywid);
            if (zltxwj != null){
                deptName = zltxwj.getFsqks();
            }
            // 申请者为 药品生产和医疗器械，直接提交到下下个环节
            if (deptName.contains(SpcyConstant.YWFL_NAME_YPSC)){
                commonFlowVo.setNextNode(ZltxwjFlowConstant.HJMC_GLZDB);

            } else if (deptName.contains(SpcyConstant.YWFL_NAME_YLQX)){
                commonFlowVo.setNextNode(ZltxwjFlowConstant.HJMC_GLZDB);
            } else {
                commonFlowVo.setNextNode("");
            }

            // 流程环节处理
            Result httpResult = handleNodeName(commonFlowVo, submitType, nowJob, ywid, opinion);
            if (!httpResult.isSuccess()) {
                return httpResult;
            }

        }else if (nowJob.getFhjmc().equals(ZltxwjFlowConstant.HJMC_ZXLD)){

            // 流程环节处理
            Result httpResult = handleNodeName(commonFlowVo, submitType, nowJob, ywid, opinion);
            if (!httpResult.isSuccess()){
                return httpResult;
            }

        }else if (nowJob.getFhjmc().equals(ZltxwjFlowConstant.HJMC_XDQR)){

            // 流程环节处理
            Result httpResult = handleNodeName(commonFlowVo, submitType, nowJob, ywid, opinion);
            if (!httpResult.isSuccess()){
                return httpResult;
            }

        }else if (nowJob.getFhjmc().equals(ZltxwjFlowConstant.HJMC_XDSH)){

            // 流程环节处理
            Result httpResult = handleNodeName(commonFlowVo, submitType, nowJob, ywid, opinion);
            if (!httpResult.isSuccess()){
                return httpResult;
            }

            if (submitType.equals(ZltxwjFlowConstant.SUBMIT_TYPE_SUBMIT)){
                // 发布-宣贯学习-环节子流程
                Result result = this.releaseXgxxJob(ywid);
                if (!result.isSuccess()){
                    log.error(result.getMessage());
                }
            }

        }else if (nowJob.getFhjmc().equals(ZltxwjFlowConstant.HJMC_SSFB)){

            // 流程环节处理
            Result httpResult = handleNodeName(commonFlowVo, submitType, nowJob, ywid, opinion);
            if (!httpResult.isSuccess()){
                return httpResult;
            }else if (submitType.equals(ZltxwjFlowConstant.SUBMIT_TYPE_SUBMIT)){
                SpcyZltxwjFlow zltxwj = spcyZltxwjFlowService.getById(ywid);
                if (zltxwj != null){
                    // 更新质量体系文件-修订状态
                    if (StringUtils.isNotBlank(zltxwj.getFpid())) {
                        SpcyZltxwjBasic zltxwjBasic = spcyZltxwjBasicService.getById(zltxwj.getFpid());
                        if (zltxwjBasic != null) {
                            zltxwjBasic.setFxdzt("");
                            spcyZltxwjBasicService.updateById(zltxwjBasic);
                        }
                    }
                    zltxwj.setFlczt(ZltxwjFlowConstant.HJMC_LCJS); // 流程结束
                    spcyZltxwjFlowService.updateById(zltxwj);
                }
                this.ysFlowToZltxwjBasic(ywid); // 移送文件到 质量体系文件资源库
            }

        }else {
            // 流程环节处理
            Result httpResult = handleNodeName(commonFlowVo, submitType, nowJob, ywid, opinion);
            if (!httpResult.isSuccess()){
                return httpResult;
            }
        }

        return Result.ok("操作成功");
    }

    public Result handleNodeName(CommonFlowVo commonFlowVo,String submitType, SpcySqsxJob job, String ywid, String opinion){
        HashMap<String, Object> map = commonFlowVo.getMap();
        String dbrid = commonFlowVo.getDbrid();// 下环节待办人
        String smgflag = commonFlowVo.getSmgflag(); // 短信发送标志
        String nextNode = ""; // 下环节名称
        boolean isSubmit = true; // 是否提交流程
        Result res = null;

        // 保存按钮
        if (submitType.equals(ZltxwjFlowConstant.SUBMIT_TYPE_SAVE)){
            res = this.updateJbxx(map, ywid, job);
            if (!res.isSuccess()){
                return res;
            }else {
                return Result.ok("保存成功");
            }
        }

        // 提交按钮
        if (submitType.equals(ZltxwjFlowConstant.SUBMIT_TYPE_SUBMIT)){
            res = this.updateJbxx(map, ywid, job);
            if (!res.isSuccess()){
                return res;
            }

            // 流程任务id
            String jobId = "";
            if (job != null){
                jobId = job.getId();
            }
            // 是否指定下环节
            if (StringUtils.isNotBlank(commonFlowVo.getNextNode())){
                nextNode = commonFlowVo.getNextNode();
            }

            // 提交流程任务,待办人是否为空，指定待办人
            if (isSubmit) {
                if (StringUtils.isBlank(dbrid)) {
                    // 提交-流程任务
                    res = this.passJob(ywid, jobId, opinion, nextNode, "");
                } else {
                    // 提交-流程任务
                    res = this.passJob(ywid, jobId, opinion, nextNode, dbrid);
                }
            }
            if (!res.isSuccess()){
                return res;
            }else {
                SpcySqsxJob nowJob = (SpcySqsxJob)res.getResult();
                // 接收返回的流程任务，如果返回的流程任务id不相等，发送短信
                if (nowJob != null && !jobId.equals(nowJob.getId()) && StringUtils.isNotBlank(smgflag) && smgflag.equals("是")){
                    busService.sendSmsToPassJob(nowJob);
                }
            }
        }

        return Result.ok("提交成功");
    }

    /**
     * 走完质量体系文件流程，将最终的文件移送到-资源库和历史库
     * @param zltxwjid 流程质量体系文件id
     */
    public Result ysFlowToZltxwjBasic(String zltxwjid){
        if (StringUtils.isBlank(zltxwjid)){
            return Result.error("质量体系文件参数为空");
        }
        boolean isAddBasic = true; // 是否更新资源库的内容

        SpcyZltxwjFlow flowZltxwj = spcyZltxwjFlowService.getById(zltxwjid);
        if (flowZltxwj == null){
            return Result.error("当前质量体系文件流程不存在，请刷新重试");
        }
        String basicId = "";

        // 判断是否绑定资源库,不存在，新增资源库，
        if (StringUtils.isBlank(flowZltxwj.getFpid())){
            SpcyZltxwjBasic newZltxwj = new SpcyZltxwjBasic();
            BeanUtil.copyProperties(flowZltxwj, newZltxwj);
            newZltxwj.setId(GetUuIdUtils.ReplaceUuId());
            newZltxwj.setFzt(SpcyConstant.Zltxwj_Zt_Yx);
            if (newZltxwj.getFssrq() == null) {
                newZltxwj.setFssrq(new Date());
            }
            if (newZltxwj.getFscrq() == null) {
                newZltxwj.setFscrq(new Date());
            }
            newZltxwj.setFwjlx(flowZltxwj.getFwjlx());
            newZltxwj.setFwjlj("");
            newZltxwj.setCreateTime(new Date());
            newZltxwj.setUpdateTime(new Date());
            spcyZltxwjBasicService.save(newZltxwj);

            String addTxwjLog = "添加质量体系文件质量员库：";
            addTxwjLog += LogUtils.MapToStringMethod(ObjectToMapUtils.objectToMap(newZltxwj));
            spcyLogService.addLogs(LogConstant.LOGS_ZLTXWJ,addTxwjLog,newZltxwj.getId(),SpcyConstant.LOGS_SYS_TYPE_XZ,SpcyConstant.LOGS_SYS_TYPE_XZ);

            basicId = newZltxwj.getId();
            flowZltxwj.setFpid(newZltxwj.getId());
            spcyZltxwjFlowService.updateById(flowZltxwj);
        }else {
            basicId = flowZltxwj.getFpid();
        }

        // 查询质量体系文件-资源库
        SpcyZltxwjBasic basicZltxwj = spcyZltxwjBasicService.getById(basicId);
        if (basicZltxwj == null){
            return Result.error("质量体系文件资源库不存在，请刷新重试");
        }

        String basicWjlj = basicZltxwj.getFwjlj(); // 资源库-文件路径
        String historyWjlj = ""; // 历史库-文件路径

        /**
         * 将资源库文件-移送到历史库中
         */
        if (StringUtils.isNotBlank(basicWjlj)) {
            String wjHz = Util.getWjHz(basicWjlj);
            String wjml = "/" + SpcyConstant.Old_Zltxwj_File_Base_Url + "/" + DateConversionUtils.DateToYear(new Date());
            String uuidName = GetUuIdUtils.ReplaceUuId() + wjHz;

            historyWjlj = wjml + "/" + basicZltxwj.getFwjmc() + uuidName;

            if (businessConstant.isEnableZltxwnjMinio){
                InputStream minioInput = spcyMinioUtils.getObject(basicWjlj);
                if (minioInput == null){
                    return Result.error("文件流不存在！");
                }
                File file = localFileUploadUtils.asFile(minioInput, wjHz);

                spcyMinioUtils.putFile(historyWjlj, new File(file.getAbsolutePath()), wjHz);
            }else {

                File dir = new File(businessConstant.UPLOAD_FILE_ROOT + wjml);
                if (!dir.exists()) {
                    dir.mkdirs();
                }

                String newWjlj = businessConstant.UPLOAD_FILE_ROOT + historyWjlj;
                FileCopyUtils.copyFile(businessConstant.UPLOAD_FILE_ROOT + basicWjlj, newWjlj);
            }

        }else {
            /**
             * 将 流程文件 移入到 资源库 中
             */

            String wjHz = Util.getWjHz(flowZltxwj.getFwjlj());
            String wjml = "/" + SpcyConstant.Old_Zltxwj_File_Base_Url + "/" + DateConversionUtils.DateToYear(new Date());
            String uuidName = GetUuIdUtils.ReplaceUuId() + wjHz;
            historyWjlj = wjml + "/" + flowZltxwj.getFwjmc() + uuidName;

            if (businessConstant.isEnableZltxwnjMinio){
                InputStream minioInput = spcyMinioUtils.getObject(flowZltxwj.getFwjlj());
                if (minioInput == null){
                    return Result.error("文件流不存在！");
                }
                File file = localFileUploadUtils.asFile(minioInput, wjHz);

                spcyMinioUtils.putFile(historyWjlj, new File(file.getAbsolutePath()), wjHz);
            }else {

                File dir = new File(businessConstant.UPLOAD_FILE_ROOT + wjml);
                if (!dir.exists()) {
                    dir.mkdirs();
                }

                String newWjlj = businessConstant.UPLOAD_FILE_ROOT + historyWjlj;
                FileCopyUtils.copyFile(businessConstant.UPLOAD_FILE_ROOT + flowZltxwj.getFwjlj(), newWjlj);
            }
        }

        /**
         * 生成质量体系文件-历史库
         */
        SpcyZltxwjHistory history = new SpcyZltxwjHistory();
        BeanUtil.copyProperties(basicZltxwj, history);
        history.setId(GetUuIdUtils.ReplaceUuId());
        history.setFpid(basicId);
        history.setFwjlj(historyWjlj);
        history.setCreateTime(new Date());
        history.setUpdateTime(new Date());
        boolean hisFlag = spcyZltxwjHistoryService.save(history);
        if (hisFlag) {
            String log = "生成质量体系文件历史库：";
            Map<String, Object> hisMap = ObjectToMapUtils.objectToMap(history);
            log += LogUtils.MapToStringMethod(hisMap);
            spcyLogService.addLogs("质量体系文件", log, basicId, SpcyConstant.LOGS_SYS_TYPE_XZ, SpcyConstant.LOGS_SYS_TYPE_XZ);
        }

        /**
         * 将质量体系文件流程最终的文件-移送到资源库中
         */
        String newBasicWjlj = ""; // 新的资源库文件路径
        if (StringUtils.isNotBlank(flowZltxwj.getFwjlj()) && isAddBasic){
            String wjHz = Util.getWjHz(flowZltxwj.getFwjlj());

            String wjml = "/" + SpcyConstant.Zltxwj_File_Base_Url;
            if (StringUtils.isNotBlank(flowZltxwj.getFtype())){
                wjml += "/" + flowZltxwj.getFtype();
            }
            wjml += "/" + DateConversionUtils.DateToYear(new Date());

            newBasicWjlj = wjml + "/" + flowZltxwj.getFwjmc() + wjHz;

            if (businessConstant.isEnableZltxwnjMinio){
                InputStream minioInput = spcyMinioUtils.getObject(flowZltxwj.getFwjlj());
                if (minioInput == null){
                    return Result.error("文件流不存在！");
                }
                File file = localFileUploadUtils.asFile(minioInput, wjHz);

                spcyMinioUtils.putFile(newBasicWjlj, new File(file.getAbsolutePath()), wjHz);
            }else {
                File dir = new File(businessConstant.UPLOAD_FILE_ROOT + wjml);
                if (!dir.exists()) {
                    dir.mkdirs();
                }

                String newWjlj = businessConstant.UPLOAD_FILE_ROOT + newBasicWjlj;
                FileCopyUtils.copyFile(businessConstant.UPLOAD_FILE_ROOT + flowZltxwj.getFwjlj(), newWjlj);
            }

            /*if (StringUtils.isNotBlank(flowZltxwj.getFjdwjlj())){
                localFileUploadUtils.deleteLocalFileUrlByZltxwj(flowZltxwj.getFjdwjlj()); // 删除流程缓存的文件
            }*/
        }

        /**
         * 修改 质量体系文件资源库信息
         */
        if (isAddBasic) {
            String oldPdfUrl = basicZltxwj.getFpdfurl();
            Map<String, Object> oldBasicMap = ObjectToMapUtils.objectToMap(basicZltxwj);
            BeanUtil.copyProperties(flowZltxwj, basicZltxwj);
            basicZltxwj.setId(basicId);
            basicZltxwj.setFwjlj(newBasicWjlj);
            basicZltxwj.setFwjlx(Util.getWjHz(newBasicWjlj));

            if (basicZltxwj.getFssrq() == null) {
                basicZltxwj.setFssrq(new Date()); // 实施日期
            }
            if (basicZltxwj.getFscrq() == null) {
                basicZltxwj.setFscrq(new Date()); // 上传日期
            }
            basicZltxwj.setUpdateTime(new Date());
            basicZltxwj.setCreateTime(new Date());
            basicZltxwj.setFpdfurl("");
            boolean updateFlag = spcyZltxwjBasicService.updateById(basicZltxwj);
            if (updateFlag) {

                localFileUploadUtils.deleteLocalFileUrlByZltxwj(basicWjlj); // 删除原资源库文件
                if (StringUtils.isNotBlank(oldPdfUrl)){
                    localFileUploadUtils.deleteLocalFileUrlByZltxwj(oldPdfUrl); // 删除原资源库文件
                }

                String zykLog = "修改资源库质量体系文件库：";
                zykLog += LogUtils.BeanModifyMsg(basicZltxwj, oldBasicMap);
                spcyLogService.addLogs("质量体系文件", zykLog, basicId, SpcyConstant.LOGS_SYS_TYPE_XG, SpcyConstant.LOGS_SYS_TYPE_XG);

                // 生产资源库文件pdf版
//                this.zltxwjToPdf(basicZltxwj);
            }
        }

        return Result.ok("操作成功");
    }

    /**
     * 生产资源库文件pdf版
     */
    public SpcyZltxwjBasic zltxwjToPdf(SpcyZltxwjBasic basicZltxwj){
        return zltxwjToPdf(basicZltxwj, true);
    }
    public SpcyZltxwjBasic zltxwjToPdf(SpcyZltxwjBasic basicZltxwj, boolean isDelete){
        if (isDelete) {
            if (StringUtils.isNotBlank(basicZltxwj.getFpdfurl())) {
                localFileUploadUtils.deleteLocalFileUrlByZltxwj(basicZltxwj.getFpdfurl());
            }
        }else {
            if (StringUtils.isNotBlank(basicZltxwj.getFpdfurl())){
                return basicZltxwj;
            }
        }

        if (StringUtils.isBlank(basicZltxwj.getFwjlx())){
            return basicZltxwj;
        }

        if (StringUtils.isBlank(basicZltxwj.getFwjlj())){
            return basicZltxwj;
        }


        // 文档才能转换
        if (!(basicZltxwj.getFwjlx().equals(".doc") || basicZltxwj.getFwjlx().equals(".docx"))){
            return basicZltxwj;
        }

        String wordUrl = ""; // 文档路径
        String parMl = ""; // pdf文件父路径
        if (businessConstant.isEnableZltxwnjMinio) {
            parMl = businessConstant.TEMPORARY_UPLOAD_MKDIR_ROOT + "/" + SpcyConstant.TEMP_WJJL_CHILD_URL;
            InputStream minioInput = spcyMinioUtils.getObject(basicZltxwj.getFwjlj());
            if (minioInput == null){
                return basicZltxwj;
            }
            File file = localFileUploadUtils.asFile(minioInput, Util.getWjHz(basicZltxwj.getFwjlj()));
            wordUrl = file.getAbsolutePath();
        }else {
            wordUrl = businessConstant.UPLOAD_FILE_ROOT + basicZltxwj.getFwjlj();

            parMl = businessConstant.UPLOAD_FILE_ROOT;
        }

        /**
         * 生产pdf文件版
         */
        String ml = "/" + SpcyConstant.Zltxwj_File_Base_Url + "/pdf/" + DateConversionUtils.DateToYear(new Date());
        File dir = new File(parMl + ml);
        if (!dir.exists()){
            dir.mkdirs();
        }
        String pdfUrl = ml + "/"+ GetUuIdUtils.ReplaceUuId()+".pdf";

        wordPdfUtils.wordToPdf(wordUrl,parMl + pdfUrl);

        boolean flag = true;
        if (businessConstant.isEnableZltxwnjMinio) {
            flag = spcyMinioUtils.putFlagFile(pdfUrl, new File(parMl + pdfUrl), Util.getWjHz(".pdf"));
        }

        if (flag) {
            basicZltxwj.setFpdfurl(pdfUrl);
            spcyZltxwjBasicService.updateById(basicZltxwj);
        }

        return basicZltxwj;
    }

    /** 历史文件库下载pdf */
    public void historyZltxwjToTempPdf(SpcyZltxwjHistory basicZltxwj, HttpServletResponse response){
        String wordUrl = ""; // 文档路径
        String parMl = ""; // pdf文件父路径
        if (businessConstant.isEnableZltxwnjMinio) {
            parMl = businessConstant.TEMPORARY_UPLOAD_MKDIR_ROOT + "/" + SpcyConstant.TEMP_WJJL_CHILD_URL;
            InputStream minioInput = spcyMinioUtils.getObject(basicZltxwj.getFwjlj());
            if (minioInput == null){
                throw new BusinessException("文件流为空！");
            }

            File file = localFileUploadUtils.asFile(minioInput, Util.getWjHz(basicZltxwj.getFwjlj()));
            wordUrl = file.getAbsolutePath();
        }else {
            wordUrl = businessConstant.UPLOAD_FILE_ROOT + basicZltxwj.getFwjlj();

            parMl = businessConstant.TEMPORARY_UPLOAD_MKDIR_ROOT + "/" + SpcyConstant.TEMP_WJJL_CHILD_URL;
        }

        /**
         * 生产pdf文件版
         */
        String pdfUrl = "/"+GetUuIdUtils.ReplaceUuId()+".pdf";
        wordPdfUtils.wordToPdf(wordUrl,parMl + pdfUrl);

        localFileUploadUtils.ejzLocalFileByZdyFile(new File(parMl+pdfUrl), response);
    }

    /**
     * 下载件压缩包-批量下载
     */
    public void downloadZipFile(String ids, HttpServletResponse response){
        if (StringUtils.isBlank(ids)){
            log.error("请选择要下载的文件");
            return;
        }
        List<String> idsList = Arrays.asList(ids.split(",|，"));
        if (CollectionUtils.isEmpty(idsList)){
            log.error("下载件压缩包-批量下载，参数错误！");
            return;
        }

        List<File> files = new ArrayList<>();
        List<String> fileNames = new ArrayList<>();
        List<SpcyZltxwjBasic> pdfWjjlList = spcyZltxwjBasicService.listByIds(idsList);
        if (CollectionUtils.isNotEmpty(pdfWjjlList)){
            for (SpcyZltxwjBasic wjjl : pdfWjjlList){
                if (StringUtils.isNotBlank(wjjl.getFwjlj())) {
                    fileNames.add(wjjl.getFwjmc()+wjjl.getFwjlx());

                    if (businessConstant.isEnableZltxwnjMinio) {
                        InputStream minioInput = spcyMinioUtils.getObject(wjjl.getFwjlj());
                        if (minioInput == null){
                            return ;
                        }
                        File file = localFileUploadUtils.asFile(minioInput, Util.getWjHz(wjjl.getFwjlj()));
                        files.add(file);

                    }else {
                        files.add(new File(businessConstant.UPLOAD_FILE_ROOT + wjjl.getFwjlj()));
                    }
                }
            }
        }

        PdfUtils.downZip(files,fileNames,response);
    }

    /**
     * 将库的文件-移送到历史库
     * @param basicZltxwj
     * @return
     */
    public Result BasicToHistory(SpcyZltxwjBasic basicZltxwj){

        // 查询质量体系文件-资源库
//        SpcyZltxwjBasic basicZltxwj = spcyZltxwjBasicService.getById(zltxwjid);
        if (basicZltxwj == null){
            return Result.error("质量体系文件资源库不存在，请刷新重试");
        }
        String basicWjlj = basicZltxwj.getFwjlj(); // 资源库-文件路径
        String historyWjlj = ""; // 历史库-文件路径

        /**
         * 将资源库文件-移送到历史库中
         */
        if (StringUtils.isNotBlank(basicWjlj)) {
            String wjHz = Util.getWjHz(basicWjlj);
            String nowDay = DateUtil.today(); // 获取当前日期 yyyy-MM-dd
            String uuidName = GetUuIdUtils.NotReplaceUuId();
            File dir = new File(businessConstant.UPLOAD_FILE_ROOT + "/" + SpcyConstant.Old_Zltxwj_File_Base_Url + "/" + nowDay);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            String newWjlj = businessConstant.UPLOAD_FILE_ROOT + "/" + SpcyConstant.Old_Zltxwj_File_Base_Url + "/" + nowDay + "/" + basicZltxwj.getFwjmc() + uuidName + wjHz;
            boolean success = FileCopyUtils.copyFile(businessConstant.UPLOAD_FILE_ROOT + basicWjlj, newWjlj);
            if (success) {
                historyWjlj = "/" + SpcyConstant.Old_Zltxwj_File_Base_Url + "/" + nowDay + "/" + basicZltxwj.getFwjmc() + uuidName + wjHz;
                // 存储旧的质量体系文件库
                localFileUploadUtils.deleteLocalFileUrlByZdy(basicWjlj); // 删除文件
            }
        }

        /**
         * 生成质量体系文件-历史库
         */
        SpcyZltxwjHistory history = new SpcyZltxwjHistory();
        BeanUtil.copyProperties(basicZltxwj, history);
        history.setId(GetUuIdUtils.ReplaceUuId());
        history.setFpid(basicZltxwj.getId());
        history.setFwjlj(historyWjlj);
        boolean hisFlag = spcyZltxwjHistoryService.save(history);
        if (hisFlag) {
            String log = "生成质量体系文件历史库：";
            Map<String, Object> hisMap = ObjectToMapUtils.objectToMap(history);
            log += LogUtils.MapToStringMethod(hisMap);
            spcyLogService.addLogs("质量体系文件", log, basicZltxwj.getId(), SpcyConstant.LOGS_SYS_TYPE_XZ, SpcyConstant.LOGS_SYS_TYPE_XZ);
        }

        return Result.ok();
    }

    /**
     * 更新基本信息
     */
    public Result updateJbxx(HashMap<String,Object> map,String ywid,SpcySqsxJob job){
        SpcyZltxwjFlow basicUpdate = spcyZltxwjFlowService.getById(ywid);
        if (basicUpdate == null){
            return Result.error("当前质量体系文件【"+ywid+"】不存在，请重试");
        }
        SpcyZltxwjFlow oldBean = basicUpdate;

        // 修改
        ConvertUtils.register(new DateConvert(), java.util.Date.class);
        try {
            BeanUtils.populate(basicUpdate,map);
            spcyZltxwjFlowService.updateById(basicUpdate);
        } catch (IllegalAccessException e) {
            log.error("出错-保存申请事项【非法访问异常】,{}",e.getMessage());
        } catch (InvocationTargetException e) {
            log.error("出错-保存申请事项【调用TargetException】,{}",e.getMessage());
        }

        // 更新质量体系文件-修订状态
        if (StringUtils.isNotBlank(basicUpdate.getFpid())) {
            SpcyZltxwjBasic zltxwjBasic = spcyZltxwjBasicService.getById(basicUpdate.getFpid());
            if (zltxwjBasic != null && StringUtils.isNotBlank(zltxwjBasic.getFxdzt())
                    && StringUtils.isNotBlank(basicUpdate.getFxglx())
                    && !zltxwjBasic.getFxdzt().equals(basicUpdate.getFxglx())) {
                zltxwjBasic.setFxdzt(basicUpdate.getFxglx());
                spcyZltxwjBasicService.updateById(zltxwjBasic);
            }
        }

        String logContent = "基本信息修改: ";
        Map<String, Object> basicMap = ObjectToMapUtils.objectToMap(oldBean);
        logContent += LogUtils.BeanModifyMsg(basicUpdate,basicMap);

        if (job == null) {
            spcyLogService.addLogs(LogConstant.LOGS_ZLTXWJ, logContent, ywid, "质量体系文件", SpcyConstant.LOGS_SYS_TYPE_XG);
        }else {
            spcyLogService.addLogs(job.getFhjmc(), logContent, ywid, LogConstant.LOGS_SQSX_BASIC, SpcyConstant.LOGS_SYS_TYPE_XG);
        }

        return Result.ok("保存成功");
    }

    /**
     * 发起修订/失效-初始化-质量体系文件流程
     * @param id 质量体系文件id
     * @param isSx 是否失效 (true/false)
     */
    public Result initZltxwjFlow(String id,boolean isSx){
        CurrentUserVo currentUser = GetCurrentUserUtils.getCurrentUser();
        if (currentUser == null){
            return Result.error("当前登录已失效，请重新登录");
        }
        if (StringUtils.isBlank(id)){
            return Result.error("质量体系文件参数不能为空");
        }
        SpcyZltxwjBasic zltxwj = spcyZltxwjBasicService.getById(id);
        if (zltxwj == null){
            return Result.error("质量体系文件不存在，请刷新重试");
        }
        if (StringUtils.isNotBlank(zltxwj.getFxdzt())){
            if (isSx) {
                return Result.error("发起"+SpcyConstant.Zltxwj_Xdlx_SX+"流程失败！,该体系文件正处于【"+zltxwj.getFxdzt()+"】环节！");
            }else {
                return Result.error("发起"+SpcyConstant.Zltxwj_Xdlx_Xd+"流程失败！该体系文件正处于【"+zltxwj.getFxdzt()+"】环节！");
            }
        }

        // 是否为失效流程
        if (isSx){
            zltxwj.setFxdzt(SpcyConstant.Zltxwj_Xdlx_SX);
        }else {
            zltxwj.setFxdzt(SpcyConstant.Zltxwj_Xdlx_Xd);
        }

        spcyZltxwjBasicService.updateById(zltxwj);

        String oldCflj = zltxwj.getFwjlj(); // 旧的文件路径
        String newCflj = "";
        if (StringUtils.isNotBlank(oldCflj)){
            String wjHz = Util.getWjHz(oldCflj);
            String nowDay = DateUtil.today(); // 获取当前日期 yyyy-MM-dd
            File dir = new File(businessConstant.UPLOAD_FILE_ROOT+"/"+SpcyConstant.Flow_Zltxwj_File_Base_Url+"/"+nowDay);
            if (!dir.exists()){
                dir.mkdirs();
            }
            String newWjlj = businessConstant.UPLOAD_FILE_ROOT + "/" + SpcyConstant.Flow_Zltxwj_File_Base_Url +"/"+nowDay+ "/" + zltxwj.getFwjmc()+wjHz;
            boolean copyFlag = FileCopyUtils.copyFile(businessConstant.UPLOAD_FILE_ROOT + oldCflj, newWjlj); // 复制文件
            if (copyFlag){
                newCflj = "/" + SpcyConstant.Flow_Zltxwj_File_Base_Url +"/"+nowDay+ "/" + zltxwj.getFwjmc()+wjHz;
            }
        }

        SpcyZltxwjFlow zltxwjFlow = new SpcyZltxwjFlow(); // 质量体系文件流程
        BeanUtil.copyProperties(zltxwj,zltxwjFlow);
        String flowId = GetUuIdUtils.ReplaceUuId(); // 质量体系文件流程id
        zltxwjFlow.setId(flowId);
        zltxwjFlow.setFsqrid(currentUser.getId());
        zltxwjFlow.setFsqr(currentUser.getName());
        zltxwjFlow.setFsqrq(new Date());
        zltxwjFlow.setFsqks(currentUser.getDeptName());
        zltxwjFlow.setFwjlj(newCflj);
        zltxwjFlow.setFpid(id); // 绑定质量体系文件
        if (isSx) {
            zltxwjFlow.setFxglx(SpcyConstant.Zltxwj_Xdlx_SX); // 默认：失效
            zltxwjFlow.setFzt(SpcyConstant.Zltxwj_Zt_Wx); // 失效流程-有效状态-无效
        }else {
            zltxwjFlow.setFxglx(SpcyConstant.Zltxwj_Xdlx_Xd); // 默认：修订
        }

        boolean save = spcyZltxwjFlowService.save(zltxwjFlow);
        if (save) {
            String log = "初始化[" + zltxwj.getFwjmc() + "]质量体系文件流程：";
            spcyLogService.addLogs(flowConstant.getFirstNode(), log, flowId, SpcyConstant.LOGS_SYS_TYPE_TJ, SpcyConstant.LOGS_SYS_TYPE_TJ);

            Result result = this.initJob(flowId, currentUser); // 初始化流程
            if (!result.isSuccess()) {
                return Result.error(result.getMessage());
            }else {
                SpcySqsxJob job = (SpcySqsxJob)result.getResult();
                return Result.ok(job);
            }
        }
        return Result.ok("操作成功");
    }

    /**
     * 发起添加-质量体系文件流程
     */
    public Result addInitZltxwjFlow(){
        CurrentUserVo currentUser = GetCurrentUserUtils.getCurrentUser();
        if (currentUser == null){
            return Result.error("当前登录已失效，请重新登录");
        }

        SpcyZltxwjFlow zltxwjFlow = new SpcyZltxwjFlow(); // 质量体系文件流程
        String flowId = GetUuIdUtils.ReplaceUuId(); // 质量体系文件流程id
        zltxwjFlow.setId(flowId);
        zltxwjFlow.setFsqrid(currentUser.getId());
        zltxwjFlow.setFsqr(currentUser.getName());
        zltxwjFlow.setFsqrq(new Date());
        zltxwjFlow.setFscrq(new Date());
        zltxwjFlow.setFsqks(currentUser.getDeptName());
        zltxwjFlow.setFwjlj("");
        zltxwjFlow.setFpid(""); // 绑定质量体系文件
        zltxwjFlow.setFxglx(SpcyConstant.Zltxwj_Xdlx_Xz); // 默认：修订
        zltxwjFlow.setFzt(SpcyConstant.Zltxwj_Zt_Yx); // 有效

        boolean save = spcyZltxwjFlowService.save(zltxwjFlow);
        if (save) {
            String log = "发起添加-质量体系文件流程：";
            spcyLogService.addLogs(flowConstant.getFirstNode(), log, flowId, SpcyConstant.LOGS_SYS_TYPE_TJ, SpcyConstant.LOGS_SYS_TYPE_TJ);

            Result result = this.initJob(flowId, currentUser); // 初始化流程
            if (!result.isSuccess()) {
                return Result.error(result.getMessage());
            }else {
                SpcySqsxJob job = (SpcySqsxJob)result.getResult();
                return Result.ok(job);
            }
        }

        return Result.ok("初始化成功");
    }

    /**
     * 删除-质量体系文件流程
     * @param zltxwjid 质量体系文件id
     */
    public Result deleteZltxwjFlow(String zltxwjid){
        if (StringUtils.isBlank(zltxwjid)){
            return Result.error("质量体系文件id不能为空");
        }
        SpcyZltxwjFlow zltxwj = spcyZltxwjFlowService.getById(zltxwjid);
        if (zltxwj == null){
            return Result.error("当前质量体系文件流程记录不存在，请刷新重试");
        }
        if (StringUtils.isNotBlank(zltxwj.getFpid())) {
            SpcyZltxwjBasic zltxwjBasic = spcyZltxwjBasicService.getById(zltxwj.getFpid());
            if (zltxwjBasic != null) {
                zltxwjBasic.setFxdzt("");
                spcyZltxwjBasicService.updateById(zltxwjBasic);
            }
        }

        spcyZltxwjFlowService.removeById(zltxwjid);
        if (StringUtils.isNotBlank(zltxwj.getFwjlj())){
            localFileUploadUtils.deleteLocalFileUrlByZltxwj(zltxwj.getFwjlj());
            if (StringUtils.isNotBlank(zltxwj.getFjdwjlj())){
                localFileUploadUtils.deleteLocalFileUrlByZltxwj(zltxwj.getFjdwjlj());
            }
        }

        spcySqsxJobService.remove(new LambdaQueryWrapper<SpcySqsxJob>().eq(SpcySqsxJob::getFpid, zltxwjid));

        String operContent = "删除质量体系文件流程信息：";
        Map<String, Object> oldMap = ObjectToMapUtils.objectToMap(zltxwj);
        operContent += LogUtils.MapToStringMethod(oldMap);
        spcyLogService.addLogs(flowConstant.getFirstNode(),operContent,zltxwjid,SpcyConstant.LOGS_SYS_TYPE_SC,SpcyConstant.LOGS_SYS_TYPE_SC);

        return Result.ok("操作成功");
    }

    /**
     * 撤回流程
     * @param jobid
     * @param opinion
     * @return
     */
    public Result returnSpBzFlow(String jobid,String opinion){
        if (StringUtils.isBlank(jobid)){
            return Result.error("参数丢失，请联系管理员");
        }
        SpcySqsxJob nowJob = spcySqsxJobService.getById(jobid);
        if (nowJob == null){
            return Result.error("当前流程任务不存在，请刷新重试");
        }
        if (StringUtils.isNotBlank(nowJob.getFblzt()) && nowJob.getFblzt().equals(SpcyConstant.BLZT_YB)){
            return Result.error("当前环节【"+nowJob.getFhjmc()+"】已经办理，无法撤回");
        }

        String nowNode = nowJob.getFhjmc(); // 当前环节
        String previousName = flowConstant.getPreviousName(nowNode); // 上环节名称

        StringBuffer logNr = new StringBuffer("质量体系文件-撤回流程：\n");

        // 判断是否为第一个环节
        if (nowNode.equals(previousName)){

            spcyZltxwjFlowService.removeById(nowJob.getFpid());
            spcySqsxJobService.removeById(jobid);
            logNr.append("环节名称").append("[").append(nowNode).append("]");

            SpcyZltxwjBasic zltxwjBasic = spcyZltxwjBasicService.getById(nowJob.getFpid());
            if (zltxwjBasic != null) {
                zltxwjBasic.setFxdzt("");
                spcyZltxwjBasicService.updateById(zltxwjBasic);
            }
        } else {
            // 上环节
            String fsyhjid = nowJob.getFsyhjid();
            if (StringUtils.isNotBlank(fsyhjid)) {
                SpcySqsxJob preJob = spcySqsxJobService.getById(fsyhjid);
                if (preJob != null) {
                    preJob.setFblzt(SpcyConstant.BLZT_DB);
                    preJob.setFthyj(opinion);
                    spcySqsxJobService.updateById(preJob);
                }
            }

            spcySqsxJobService.removeById(jobid);
            logNr.append("环节名称").append("[").append(nowNode).append("]");
        }

        if (StringUtils.isNotBlank(opinion)){
            logNr.append("\n").append("撤回意见").append("[").append(opinion).append("]。");
        }
        spcyLogService.addLogs(nowNode,logNr.toString(),nowJob.getFpid(),SpcyConstant.LOGS_SYS_TYPE_TH,SpcyConstant.LOGS_SYS_TYPE_TH);

        return Result.ok("撤回成功");
    }

    /**
     * 获取当前流程任务相关信息
     * @param jobid 流程任务id
     */
    public Map getJobConcernByJobId(String jobid){
        Map map = new HashMap();

        // 当前流转记录
        SpcySqsxJob job = spcySqsxJobService.getById(jobid);
        if (job == null){
            log.error("当前流程任务id为【{}】的流转记录不存在",jobid);
            return map;
        }
        String currentNode = job.getFhjmc();
        String zltxwjid = job.getFpid();
        if (org.apache.commons.lang3.StringUtils.isBlank(zltxwjid)){
            log.error("当前流程任务id为【{}】的流转记录中的质量体系文件id为空",jobid);
            return map;
        }

        // 质量体系文件基本信息
        String deptName = "";
        SpcyZltxwjFlow zltxwj = spcyZltxwjFlowService.getById(zltxwjid);
        if (zltxwj == null){
            log.error("当前流程任务id为【{}】的流转记录中的质量体系文件id{}为空",jobid,zltxwjid);
            return map;
        }
        deptName = zltxwj.getFsqks();

        // 流程任务流传记录
//        List<SpcySqsxJob> jobList = this.getJobListBySqsxId(zltxwjid);

        // 申请事项相关文件记录

        // 获取下环节待办人
        String nextNode = ""; // 下环节名称
        // 申请者为 药品生产和医疗器械，直接提交到下下个环节
        if (currentNode.equals(ZltxwjFlowConstant.HJMC_KSFH) && deptName.contains(SpcyConstant.YWFL_NAME_YPSC)){
            nextNode = ZltxwjFlowConstant.HJMC_GLZDB;

        } else if (currentNode.equals(ZltxwjFlowConstant.HJMC_KSFH) && deptName.contains(SpcyConstant.YWFL_NAME_YLQX)){
            nextNode = ZltxwjFlowConstant.HJMC_GLZDB;

        } else {
            nextNode = flowConstant.getNextNodeName(job.getFhjmc());
        }

        Map nextDbr = this.getNodeDbr(zltxwjid, nextNode,"");
        List<AgentVo> dbrListByMap = busService.getDbrListByMap(nextDbr);

        map.put("zltxwj",zltxwj); // 质量体系文件基本信息
        map.put("job",job); // 当前流转记录
//        map.put("jobHistoryList",jobList); // 流程任务流传记录
        map.put("nextNodeDbrList",dbrListByMap); // 下环节待办人list
        map.put("nextNode",nextNode);

        return map;
    }

    /**
     * 获取申请事项-流转记录
     */
    public List<SpcySqsxJob> getJobListBySqsxId(String sqid){
        LambdaQueryWrapper<SpcySqsxJob> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(SpcySqsxJob::getFlcmc, flowConstant.getFlowName());
        queryWrapper.eq(SpcySqsxJob::getFpid, sqid);
        queryWrapper.orderByAsc(SpcySqsxJob::getCreateTime);
        queryWrapper.orderByAsc(SpcySqsxJob::getFfssj);
        List<SpcySqsxJob> jobList = spcySqsxJobService.list(queryWrapper);

        return jobList;
    }

    /**
     * 批量打印流转审批表
     * @param map ids | 质量体系文件zltxwjid,多个英文逗号拼接
     * @return
     */
    public HttpResult queryPrintZltxwjTable(HashMap<String,String> map){
        Map resultMap = new HashMap();

        String ids = map.get("ids");
        if (StringUtils.isBlank(ids)){
            return HttpResult.error("参数不能为空");
        }
        List<String> idsList = StringPatternUtils.getListByIds(ids);
        if (CollectionUtils.isEmpty(idsList)){
            return HttpResult.error("传递的参数规则错误，请联系管理员");
        }
        List<SpcyZltxwjFlow> txwjList = spcyZltxwjFlowService.listByIds(idsList);
        if (CollectionUtils.isEmpty(txwjList)){
            return HttpResult.error("所选的体系文件不存在，请刷新并重试");
        }
        List<Map> resultList = new ArrayList<>();
        for (SpcyZltxwjFlow flow : txwjList){
            Map result = new HashMap();
            result.put("zltxwj",flow);

            List<Map> jobMapList = new ArrayList<>();
            // 当前记录的流程记录
            List<SpcySqsxJob> jobList = spcySqsxJobService.list(new LambdaQueryWrapper<SpcySqsxJob>()
                    .eq(SpcySqsxJob::getFpid, flow.getId())
                    .eq(SpcySqsxJob::getFlcmc, flowConstant.getFlowName())
                    .orderByAsc(SpcySqsxJob::getFfssj));
            if (CollectionUtils.isNotEmpty(jobList)){
                Map jobMap = null;
                for (SpcySqsxJob job : jobList){
                    jobMap = new HashMap();
                    jobMap.put("fhjmc", job.getFhjmc()); // 环节名称
                    jobMap.put("fuserid", job.getFdbrid().split(",|，")[0]); // 办理id
                    jobMap.put("username", job.getFdbr().split(",|，")[0]); // 姓名
                    jobMap.put("fblsj", job.getFblsj()); // 办理时间
                    jobMap.put("opinion", job.getFblyj()); // 办理意见
                    jobMapList.add(jobMap);
                }
            }
            result.put("jobList",jobMapList);
            resultList.add(result);
        }

        resultMap.put("printList", resultList);
        return HttpResult.ok(resultMap);
    }

    /**
     * 上传文件-宣贯学习文件
     * @param uploadFile 文件数组
     * @param zltxwjid 流程质量体系文件id
     */
    public Result uploadXgxxFile(MultipartFile[] uploadFile,String zltxwjid){

        if (StringUtils.isEmpty(zltxwjid)){
            return Result.error("质量体系文件参数不能为空");
        }

        if (uploadFile == null || uploadFile.length == 0) {
            return Result.error("上传失败,请先选择文件");
        }

        for (MultipartFile file : uploadFile) {

            String originalFilename = file.getOriginalFilename();
            // 文件类型
            String wjlx = originalFilename.substring(originalFilename.lastIndexOf("."));

            // 文件名
            String fileName = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf("."));

            SpcySqsxWjjl spcySqsxWjjl = new SpcySqsxWjjl();

            String sjmc = ZltxwjFlowConstant.FILE_TYPE_XGQKFJ + "-" + GetUuIdUtils.NotReplaceUuId();

            String wjccmc = sjmc + wjlx;

            String ml = SpcyConstant.Flow_Zltxwj_File_Base_Url + "/" + DateConversionUtils.DateToYear(new Date());

            localFileUploadUtils.uploadZdyFile(file, wjccmc, ml, true); // 上传文件

            String Id = GetUuIdUtils.NotReplaceUuId();
            spcySqsxWjjl.setId(Id);
            spcySqsxWjjl.setFpid(zltxwjid);
            spcySqsxWjjl.setFwjxsmc(fileName);
            spcySqsxWjjl.setFwjlx(wjlx);
            spcySqsxWjjl.setFwjlx1(ZltxwjFlowConstant.FILE_TYPE_XGQKFJ);
            spcySqsxWjjl.setFwjlx2(ZltxwjFlowConstant.FILE_TYPE_XGQKFJ);
            spcySqsxWjjl.setFwjccmc(wjccmc);
            String cflj = "/" + ml + "/" + wjccmc;
            spcySqsxWjjl.setFcflj(cflj);
            boolean flag = spcySqsxWjjlService.save(spcySqsxWjjl);
            if (flag) {
                String czContent = "宣传学习-上传文件: ";
                Map<String, Object> wjjlMap = ObjectToMapUtils.objectToMap(spcySqsxWjjl);
                czContent += LogUtils.MapToStringMethod(wjjlMap);
                spcyLogService.addLogs(LogConstant.LOGS_ZLTXWJ + "-宣传学习", czContent, zltxwjid, LogConstant.LOGS_SQSX_WJJL, SpcyConstant.LOGS_SYS_TYPE_BC);
            }

        }

        return Result.ok("操作成功");
    }

    /**
     * 下载文件-宣贯学习文件
     * @param id 文件记录id
     */
    public void downloadXgxxFile(String id, HttpServletResponse response){
        if (StringUtils.isBlank(id)){
            throw new BusinessException("下载失败，文件记录参数为空！");
        }
        SpcySqsxWjjl wjjl = spcySqsxWjjlService.getById(id);
        if (wjjl == null){
            throw new BusinessException("下载失败，文件记录不存在，请刷新重试！");
        }
        if (StringUtils.isBlank(wjjl.getFcflj())){
            throw new BusinessException("下载失败，文件记录中的附件为空！");
        }

        localFileUploadUtils.ejzLocalFileURlByZdy(wjjl.getFcflj(), true, response);
    }

    /**
     * 删除文件-宣贯学习文件
     * @param id 文件记录id
     */
    public Result deleteXgxxFile(String id){
        if (StringUtils.isBlank(id)){
            throw new BusinessException("删除文件失败，文件记录参数为空！");
        }

        SpcySqsxWjjl wjjl = spcySqsxWjjlService.getById(id);
        if (wjjl == null){
            throw new BusinessException("删除文件失败，文件记录不存在，请刷新重试！");
        }

        spcySqsxWjjlService.removeById(id);

        if (StringUtils.isNotBlank(wjjl.getFcflj())) {
            localFileUploadUtils.deleteLocalFileUrlByZdy(wjjl.getFcflj(),true);
        }


        return Result.ok("操作成功");
    }

    /**
     * 查询文件-宣贯学习文件
     * @param zltxwjid 流程质量体系文件id
     */
    public HttpResult queryXgxxFile(String zltxwjid){
        if (StringUtils.isBlank(zltxwjid)){
            throw new BusinessException("质量体系文件参数不能为空");
        }
        List<SpcySqsxWjjl> wjjlList = spcySqsxWjjlService.list(new LambdaQueryWrapper<SpcySqsxWjjl>()
                .eq(SpcySqsxWjjl::getFpid, zltxwjid)
                .eq(SpcySqsxWjjl::getFwjlx1, ZltxwjFlowConstant.FILE_TYPE_XGQKFJ)
                .orderByDesc(SpcySqsxWjjl::getCreateTime));

        return HttpResult.ok(wjjlList);
    }

    /**
     * 发布-宣贯学习-环节流程
     * @param zltxwjid 流程质量体系文件id
     */
    public Result releaseXgxxJob(String zltxwjid){
        CurrentUserVo currentUser = GetCurrentUserUtils.getCurrentUser();
        if (currentUser == null){
            throw new BusinessException("当前登录已失效，请重新登录！");
        }

        if (StringUtils.isBlank(zltxwjid)){
            log.error("质量体系文件参数为空，请联系管理员！");
            return Result.error("质量体系文件参数为空，请联系管理员！");
        }
        SpcyZltxwjFlow zltxwj = spcyZltxwjFlowService.getById(zltxwjid);
        if (zltxwj == null){
            log.error("前质量体系文件数据不存在，请刷新重试并联系管理员！");
            return Result.error("当前质量体系文件数据不存在，请刷新重试并联系管理员！");
        }

        if (StringUtils.isBlank(zltxwj.getFxgxxryid())){
            log.error("发布失败，请选择并保存宣贯学习所需的人员！");
            return Result.error("发布失败，请选择并保存宣贯学习所需的人员！");
        }

        // 宣贯学习人员
        List<String> userIds = StringPatternUtils.getListByIds(zltxwj.getFxgxxryid());
        List<YcSysUser> userList = ycSysUserService.listByIds(userIds);
        if (CollectionUtils.isNotEmpty(userList)){
            for (YcSysUser user : userList){
                // 新增-宣贯学习-环节待办
                this.initSubJob(zltxwjid,ZltxwjFlowConstant.HJMC_XGXX,user.getId(),user.getRealname(),ZltxwjFlowConstant.DEFAULT_XGXX_OPINION_WXX,currentUser);
            }
        }

        return Result.ok("操作成功");
    }

    /**
     * 办结-宣贯学习-环节流程
     */
    public Result completionXgxxJob(String jobid){
        CurrentUserVo currentUser = GetCurrentUserUtils.getCurrentUser();
        if (currentUser == null){
            return Result.error("当前登录已失效，请重新登录！");
        }
        if (StringUtils.isBlank(jobid)){
            return Result.error("流程任务参数为空，请联系管理员！");
        }
        SpcySqsxJob job = spcySqsxJobService.getById(jobid);
        if (job == null){
            return Result.error("当前流程任务不存在，请刷新重试并联系管理员！");
        }

        // 办结流程
        this.doJob(job,currentUser,ZltxwjFlowConstant.DEFAULT_XGXX_OPINION_YXX);

        return Result.ok();
    }

    /**
     * 初始化-指定环节-子流程环节
     * @param sqid 流程申请id
     * @param nextNodeName 指定环节
     * @param nextNodeDbrIds 环节待办人id
     * @param nextNodeDbrs 环节待办人
     * @param opinion 意见
     * @param currentUser 当前登录人
     * @return
     */
    public Result initSubJob(String sqid, String nextNodeName,String nextNodeDbrIds,String nextNodeDbrs,String opinion,CurrentUserVo currentUser){
        if (StringUtils.isBlank(nextNodeName)){
            return Result.error("环节参数为空！");
        }

        if (StringUtils.isBlank(nextNodeDbrIds)){
            return Result.error("待办人参数为空！");
        }

        if (StringUtils.isBlank(nextNodeDbrs)){
            return Result.error("待办人名称参数为空！");
        }

        SpcySqsxJob job = new SpcySqsxJob();
        job.setId(GetUuIdUtils.NotReplaceUuId());
        job.setFsyhjid("");
        job.setFpid(sqid);
        job.setFhjmc(nextNodeName);
        if (currentUser != null) {
            job.setFfsrid(currentUser.getId());
            job.setFfsrmc(currentUser.getName());
        }
        if (StringUtils.isNotBlank(opinion)){
            job.setFblyj(opinion);
        }
        job.setFfssj(new Date());

        job.setFdbrid(nextNodeDbrIds);
        job.setFdbr(nextNodeDbrs);
        job.setFydbrid(nextNodeDbrIds);
        job.setFydbr(nextNodeDbrs);
        job.setFblfs(flowConstant.getBlfs(nextNodeName));
        job.setFblzt(SpcyConstant.BLZT_DB);
        job.setFlcmc(flowConstant.getFlowName());
        spcySqsxJobService.save(job);

        return Result.ok(job);
    }

    /**
     * 初始化任务
     * @param sqId 申请id
     * @param currentUser 当前登录人
     * @return
     */
    public Result initJob(String sqId, CurrentUserVo currentUser){
        String nodeName = flowConstant.getFirstNode();
        //需要校验是否已经初始化过
        List<SpcySqsxJob> list = spcySqsxJobService.list(new LambdaQueryWrapper<SpcySqsxJob>()
                .eq(SpcySqsxJob::getFpid, sqId)
                .eq(SpcySqsxJob::getFhjmc, nodeName)
                .eq(SpcySqsxJob::getFlcmc, flowConstant.getFlowName())
        );
        if(list.size()>0){
            return Result.error("当前质量体系文件流程已经初始化了。");
        }
        return this.initJob(flowConstant,sqId,currentUser);
    }

    /**
     * 提交当前环节的待办记录
     *  @param sqId 申请id
     *  @param jobId 当前环节id
     *  @param opinion 办理意见
     */
    public Result passJob(String sqId, String jobId, String opinion,String nextNodeName,String nextNodeDbrIds){
        //处理业务表的逻辑
        Result httpResult = this.passJob(flowConstant, sqId, jobId, opinion, nextNodeName, nextNodeDbrIds);
        return httpResult;
    }

    /**
     * 办理环节
     * @param job
     * @param currentUser
     */
    private Result doJob(SpcySqsxJob job, CurrentUserVo currentUser, String opinion){
        String blrId = "";
        String blr = "";
        if (currentUser != null) {
            blrId = currentUser.getId();
            blr = currentUser.getName();
        }
        if (job == null){
            return Result.error("当前流程任务不存在，请重试");
        }
        if(SpcyConstant.BLZT_YB.equals(job.getFblzt())){
            return Result.error("当前任务已提交");
        }
        if(StringUtils.isBlank(job.getFdbrid())){
            return Result.error("当前任务未指定办理人");
        }
        if(!job.getFdbrid().contains(blrId)){
            return Result.error("当前登录用户无此任务的办理权限");
        }
        // 办理方式 竞争办理 、多人线性办理 、多人并行办理
        String blfs = job.getFblfs();
        if(StringUtils.isBlank(blfs)||blfs.equals(SpcyConstant.BLFS_DRJJ)){
            job.setFblr(blr);
            job.setFblsj(new Date());
            job.setFblyj(opinion);
            job.setFblzt(SpcyConstant.BLZT_YB);

            // 审评查验流程 计算 办理天数、是否超时
            /*if (StringUtils.isNotBlank(job.getFlcmc()) && job.getFlcmc().contains(YpscFlowConstant.LCMC_LIKE_SPCYLC)) {
                job.setFblts(flowJobBlsxService.jsTwoDateBetweenDays(job.getFfssj(), job.getFblsj())); // 办理天数
                job.setFsfcs(flowJobBlsxService.isDateBetweenSfcs(job.getFblts(), job.getFjzblts())); // 办理是否超时
            }*/

            spcySqsxJobService.updateById(job);
            return Result.ok(job);
        }else if(blfs.equals(SpcyConstant.BLFS_DRXX)  || blfs.equals(SpcyConstant.BLFS_DRBX)){
            //先根据多个人线性和多人并行的逻辑获得下一办理人
            String nextBlrId ="";
            String nextBlr ="";
            if(blfs.equals(SpcyConstant.BLFS_DRXX)){
                String ydbrIds[] = job.getFydbrid().split(",");
                String ydbrs[] = job.getFydbr().split(",");
                for (int i=0;i<ydbrIds.length;i++){
                    String dbrId = ydbrIds[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if(dbrId.equals(blrId)){
                        if(i+1<ydbrIds.length){
                            nextBlrId=ydbrIds[i+1];
                            nextBlr=ydbrs[i+1];
                            break;
                        }
                    }
                }
            }else{
                String dbrIds[] = job.getFdbrid().split(",");
                String dbrs[] = job.getFdbr().split(",");
                for (int i=0;i<dbrIds.length;i++){
                    String dbrId = dbrIds[i];
                    String dbr = dbrs[i];
                    //不考虑办理人id重复出现（一个人办多次）的情况
                    if(!dbrId.equals(blrId)){
                        nextBlrId=nextBlrId+(StringUtils.isBlank(nextBlrId)?"":",")+dbrId;
                        nextBlr=nextBlr+(StringUtils.isBlank(nextBlr)?"":",")+dbr;
                    }
                }
            }

            //如果存在下一办理人 就继续待办，多人办理意见用@@分隔，办理时间、办理人、意见 用|分隔
            job.setFblr(blr);
            job.setFblsj(new Date());
            String blyj=(job.getFblyj()==null?"":job.getFblyj())+(StringUtils.isBlank(job.getFblyj())?"":"@@")+ DateConversionUtils.DateToString(new Date()) +"|"+blr+"|"+ opinion;
            job.setFblyj(blyj);
            if(StringUtils.isBlank(nextBlrId)){
                job.setFblzt(SpcyConstant.BLZT_YB);
            }else{
                job.setFblzt(SpcyConstant.BLZT_DB);
                job.setFdbrid(nextBlrId);
                job.setFdbr(nextBlr);
            }
            spcySqsxJobService.updateById(job);
            return Result.ok(job);
        }
        return Result.error("待办任务未指定办理方式");
    }

    /**
     * 创建下环节流程任务
     * @param sqId 申请id
     * @param currentJob
     * @param currentUser
     * @param nextNodeName
     * @param nextNodeDbrIds
     * @return
     */
    public Result createNextJob(String sqId,SpcySqsxJob currentJob, CurrentUserVo currentUser,String nextNodeName,String nextNodeDbrIds){
        if (currentJob != null) {
            nextNodeName = getNextNodeName(currentJob.getFhjmc(), nextNodeName);
        }else {
            if (StringUtils.isBlank(nextNodeName)){
                return Result.error("下环节不能为空");
            }
        }
        if(nextNodeName.equals(YlqxFlowConstant.HJMC_LCJS)){
            SpcySqsxJob job = new SpcySqsxJob();

            return Result.ok("操作成功");
        }
        Map map = this.getNodeDbr(sqId,nextNodeName,nextNodeDbrIds);
        nextNodeDbrIds = map.get("dbrId").toString();
        String nextNodeDbrs = map.get("dbr").toString();
        if(StringUtils.isBlank(nextNodeDbrIds)){
            return Result.error("获取不到下一环节待办人");
        }
        SpcySqsxJob job = new SpcySqsxJob();
        job.setId(GetUuIdUtils.NotReplaceUuId());
        if(currentJob != null){
            job.setFsyhjid(currentJob.getId());
        }
        job.setFpid(sqId);
        job.setFhjmc(nextNodeName);
        if (currentUser != null) {
            job.setFfsrid(currentUser.getId());
            job.setFfsrmc(currentUser.getName());
        }
        job.setFfssj(new Date());

        job.setFdbrid(nextNodeDbrIds);
        job.setFdbr(nextNodeDbrs);
        job.setFydbrid(nextNodeDbrIds);
        job.setFydbr(nextNodeDbrs);
        job.setFblzt(SpcyConstant.BLZT_DB);
        spcySqsxJobService.save(job);
        return Result.ok(job);
    }

    /**
     *
     * @param currentNodeName 可为空(如果为空，nextNodeName不为空)
     * @param nextNodeName 可为空(如果为空，currentNodename不为空)
     * @return
     */
    private String getNextNodeName(String  currentNodeName,String nextNodeName){
        if (StringUtils.isNotBlank(nextNodeName)){
            return nextNodeName;
        }else{
            return flowConstant.getNextNodeName(currentNodeName);
        }
    }

    // 获取当前环节待办人
    public Map getNodeDbr(String ywid,String nodeName, String dbrIds){
        Map map = new HashMap();
        String dbrId = "";
        String dbr = "";
        if(StringUtils.isNotBlank(dbrIds)){
            dbr = getDbrsByIds(dbrIds);
            dbrId = dbrIds;
        }else{
            String deptName = "";
            SpcyZltxwjFlow zltxwj = spcyZltxwjFlowService.getById(ywid);
            if (zltxwj != null){
                deptName = zltxwj.getFsqks();
            }

            // 申请
            if (nodeName.equals(ZltxwjFlowConstant.HJMC_SQ)){
                if (zltxwj != null) {
                    dbrId = zltxwj.getFsqrid();
                    dbr = zltxwj.getFsqr();
                }
            }

            // 科室复核
            if (nodeName.equals(ZltxwjFlowConstant.HJMC_KSFH)){
                // 科室负责人
                Map kzMap = getKsfzrByDeptName(deptName);
                dbrId = kzMap.get("dbrId").toString();
                dbr = kzMap.get("dbr").toString();
            }


            // 分管领导
            if (nodeName.equals(ZltxwjFlowConstant.HJMC_FGLD)) {
                Map kzMap = null;
                // 申请者部门为，药品生成和医疗器械，
                if (deptName.contains(SpcyConstant.YWFL_NAME_YPSC)){
                    kzMap = getGlzdb();

                } else if (deptName.contains(SpcyConstant.YWFL_NAME_YLQX)){
                    kzMap = getGlzdb();

                } else {
                    kzMap = getKsFgldByDeptName(deptName);
                }
                // 分管领导
                dbrId = kzMap.get("dbrId").toString();
                dbr = kzMap.get("dbr").toString();
            }

            // 质量负责人
            if (nodeName.equals(ZltxwjFlowConstant.HJMC_GLZDB)) {
                // 代表为
                Map kzMap = getGlzdb();
                dbrId = kzMap.get("dbrId").toString();
                dbr = kzMap.get("dbr").toString();
            }

            // 中心领导
            if (nodeName.equals(ZltxwjFlowConstant.HJMC_ZXLD)) {
                // 中心领导（蒋受军）药品生产分管领导
                Map kzMap = getZxld();
                dbrId = kzMap.get("dbrId").toString();
                dbr = kzMap.get("dbr").toString();
            }

            // 修订确认
            if (nodeName.equals(ZltxwjFlowConstant.HJMC_XDQR)) {
                // 质量管理与科研科-质量体系文件负责人
                Map kzMap = getzltxwjfzrByDeptName(SpcyConstant.DEPT_NAME_ZHYWK);
                dbrId = kzMap.get("dbrId").toString();
                dbr = kzMap.get("dbr").toString();
            }

            // 修订审核
            if (nodeName.equals(ZltxwjFlowConstant.HJMC_XDSH)){
                // 质量管理与科研科-科室负责人
                Map kzMap = getKsfzrByDeptName(SpcyConstant.DEPT_NAME_ZHYWK);
                dbrId = kzMap.get("dbrId").toString();
                dbr = kzMap.get("dbr").toString();
            }

            // 宣贯效果评价
            if (nodeName.equals(ZltxwjFlowConstant.HJMC_XGXGPJ)){
                // 质量管理与科研科-质量体系文件负责人
                Map kzMap = getzltxwjfzrByDeptName(SpcyConstant.DEPT_NAME_ZHYWK);
                dbrId = kzMap.get("dbrId").toString();
                dbr = kzMap.get("dbr").toString();
            }

            // 实施发布
            if (nodeName.equals(ZltxwjFlowConstant.HJMC_SSFB)){
                // 质量管理与科研科-科室负责人
                Map kzMap = getKsfzrByDeptName(SpcyConstant.DEPT_NAME_ZHYWK);
                dbrId = kzMap.get("dbrId").toString();
                dbr = kzMap.get("dbr").toString();
            }

        }

        map.put("dbrId",dbrId);
        map.put("dbr",dbr);
        return map;
    }

    // 获取当前环节待办人
    public Map getNodeDbr(String nodeName, String dbrIds){
        return this.getNodeDbr(null,nodeName,dbrIds);
    }

    // 根据待办人id，获取名称拼接起来
    private String getDbrsByIds(String dbrIds){
        //把待办人按id查出来  把名字拼起来
        String dbr = "";
        List<String> dbrIdsList = Arrays.asList(dbrIds.split(","));
        List<YcSysUser> sysUserList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(dbrIdsList)){
            sysUserList = ycSysUserService.listByIds(dbrIdsList);
        }

        if (CollectionUtils.isNotEmpty(sysUserList)){
            for (YcSysUser user : sysUserList){
                dbr += user.getRealname() + ",";
            }
        }

        return dbr;
    }

    // 对应科室的 科室负责人
    public Map getKsfzrByDeptName(String deptName){
        Map map = new HashMap();
        String dbrId = "";
        String dbr = "";
        List<GetKsKz> ksKzObject = new ArrayList<>();
        ksKzObject = ycSysUserService.getKsKzObject(deptName, SpcyConstant.GW_NAME_KZ);
        if (CollectionUtils.isNotEmpty(ksKzObject)) {
            for (GetKsKz ksKz : ksKzObject) {
                dbrId += ksKz.getId()+",";
                dbr += ksKz.getRealname()+",";
            }
        }

        map.put("dbrId",dbrId);
        map.put("dbr",dbr);
        return map;
    }

    // 获取对应科室的 分管领导
    public Map getKsFgldByDeptName(String deptName){
        Map map = new HashMap();
        String dbrId = "";
        String dbr = "";

        YcSysUser fgldUserBydept = sysUserFgldService.getFgldUserBydept(deptName);
        if (fgldUserBydept != null) {
            dbrId = fgldUserBydept.getId();
            dbr = fgldUserBydept.getRealname();
        }

        map.put("dbrId",dbrId);
        map.put("dbr",dbr);
        return map;
    }

    // 中心领导
    public Map getZxld(){
        Map map = new HashMap();
        String dbrId = "";
        String dbr = "";
        // 中心主任
        List<YcSysUser> zxzrList = ycSysUserService.list(new LambdaQueryWrapper<YcSysUser>()
                .eq(YcSysUser::getOrgName, SpcyConstant.ORG_NAME_ZXZR));
        if (CollectionUtils.isNotEmpty(zxzrList)){
            dbrId = zxzrList.get(0).getId();
            dbr = zxzrList.get(0).getRealname();
        }

        map.put("dbrId",dbrId);
        map.put("dbr",dbr);
        return map;
    }

    // 质量负责人
    public Map getGlzdb(){
        Map map = new HashMap();
        String dbrId = "";
        String dbr = "";

        List<GetKsKz> ksKzObject = new ArrayList<>();
        ksKzObject = ycSysUserService.getKsKzObject("", SpcyConstant.GW_ZLFZR);

        if (CollectionUtils.isNotEmpty(ksKzObject)) {
            for (GetKsKz ksKz : ksKzObject) {
                dbrId += ksKz.getId()+",";
                dbr += ksKz.getRealname()+",";
            }
        }

        map.put("dbrId",dbrId);
        map.put("dbr",dbr);
        return map;
    }

    // 对应科室的 质量体系文件负责人
    public Map getzltxwjfzrByDeptName(String deptName){
        Map map = new HashMap();
        String dbrId = "";
        String dbr = "";
        List<GetKsKz> ksKzObject = new ArrayList<>();
        ksKzObject = ycSysUserService.getKsKzObject(deptName, SpcyConstant.GW_ZLTXWJ_FZR);

        if (CollectionUtils.isNotEmpty(ksKzObject)) {
            for (GetKsKz ksKz : ksKzObject) {
                dbrId += ksKz.getId()+",";
                dbr += ksKz.getRealname()+",";
            }
        }

        map.put("dbrId",dbrId);
        map.put("dbr",dbr);
        return map;
    }
}
